package org.csu.mybigpro.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource; // 确保引入 Resource
import org.csu.mybigpro.DTO.ClassroomBookingDTO;
import org.csu.mybigpro.DTO.ClassroomDTO;
import org.csu.mybigpro.common.CommonResponse;
import org.csu.mybigpro.domain.Classroom; // 导入 Classroom
import org.csu.mybigpro.domain.ClassroomBooking;
import org.csu.mybigpro.domain.User; // 导入 User
import org.csu.mybigpro.persistence.ClassroomMapper; // 导入 ClassroomMapper
import org.csu.mybigpro.persistence.UserMapper; // 导入 UserMapper
import org.csu.mybigpro.service.ClassroomBookingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections; // 导入 Collections
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/classroom-booking")
public class ClassroomBookingController {

    @Autowired
    private ClassroomBookingService bookingService;

    @Resource // 注入 UserMapper
    private UserMapper userMapper;

    @Resource // 注入 ClassroomMapper
    private ClassroomMapper classroomMapper;

    // 教师提交教室借用申请
    @PostMapping("/apply")
    public CommonResponse<?> apply(@RequestBody ClassroomBooking booking) {
        // 设置申请时间 & 状态默认待审核（0）
        booking.setApplyTime(LocalDateTime.now());
        booking.setStatus(0); // 0: 待审批
        boolean result = bookingService.save(booking);
        if (result) {
            return CommonResponse.createForSuccess("申请提交成功");
        }
        return CommonResponse.createForError("申请提交失败");
    }

    // 教师查看自己的借用记录（支持按教室号和状态查询，分页）
    @GetMapping("/my")
    public CommonResponse<IPage<ClassroomBookingDTO>> myBookings(
            @RequestParam Long teacherId,
            @RequestParam(required = false) String classroomNumber, // 更改为教室号
            @RequestParam(required = false) Integer status,
            @RequestParam(defaultValue = "1") long pageNum,
            @RequestParam(defaultValue = "10") long pageSize) {

        QueryWrapper<ClassroomBooking> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("teacher_id", teacherId);

        // 如果传入了教室号，先根据教室号查询教室ID
        if (classroomNumber != null && !classroomNumber.trim().isEmpty()) {
            QueryWrapper<Classroom> classroomQueryWrapper = new QueryWrapper<>();
            classroomQueryWrapper.like("room_number", classroomNumber);
            Classroom classroom = classroomMapper.selectOne(classroomQueryWrapper);
            if (classroom != null) {
                queryWrapper.eq("classroom_id", classroom.getId());
            } else {
                // 如果没有找到对应的教室，则返回空列表，避免查询所有
                return CommonResponse.createForSuccess(new Page<ClassroomBookingDTO>(pageNum, pageSize, 0L));
            }
        }

        if (status != null) {
            queryWrapper.eq("status", status);
        }

        // 按照申请时间倒序排列
        queryWrapper.orderByDesc("apply_time");

        IPage<ClassroomBooking> bookingPage = bookingService.page(new Page<>(pageNum, pageSize), queryWrapper);

        // 将 ClassroomBooking 转换为 ClassroomBookingDTO
        List<ClassroomBookingDTO> dtoList = bookingPage.getRecords().stream().map(booking -> {
            ClassroomBookingDTO dto = new ClassroomBookingDTO();
            dto.setId(booking.getId());
            dto.setStatus(booking.getStatus());
            dto.setApplyTime(booking.getApplyTime());
            dto.setReviewTime(booking.getReviewTime());
            dto.setRemark(booking.getRemark());
            dto.setPurpose(booking.getPurpose());
            dto.setStartTime(booking.getStartTime());
            dto.setEndTime(booking.getEndTime());
            dto.setReviewerId(booking.getReviewerId());

            // 获取教师姓名
            User user = userMapper.selectById(booking.getTeacherId());
            dto.setTeacherName(user != null ? user.getName() : null);
            dto.setTeacherId(booking.getTeacherId());

            // 获取教室编号 和 原始的 classroomId
            Classroom classroom = classroomMapper.selectById(booking.getClassroomId());
            dto.setClassroomNumber(classroom != null ? classroom.getRoomNumber() : null); // <--- 设置教室号
            dto.setClassroomId(booking.getClassroomId()); // 保留原始ID

            return dto;
        }).collect(Collectors.toList());

        // 创建新的 IPage 对象，用于返回 DTO 列表和分页信息
        // 明确指定 Page 的泛型类型，解决之前的编译问题
        Page<ClassroomBookingDTO> dtoPage = new Page<ClassroomBookingDTO>(bookingPage.getCurrent(), bookingPage.getSize(), bookingPage.getTotal());
        dtoPage.setRecords(dtoList);

        return CommonResponse.createForSuccess(dtoPage);
    }

    // 教师撤销借用申请
    @DeleteMapping("/cancel")
    public CommonResponse<?> cancelBooking(@RequestParam Long id, @RequestParam Long teacherId) {
        ClassroomBooking booking = bookingService.getById(id);
        if (booking == null || !booking.getTeacherId().equals(teacherId)) {
            return CommonResponse.createForError("无效的借用申请或权限不足");
        }
        if (booking.getStatus() != 0) { // 只有待审批的可以撤销
            return CommonResponse.createForError("该申请已被审批，无法撤销");
        }
        booking.setStatus(3); // 状态设为已撤销 (3)
        boolean updated = bookingService.updateById(booking);
        return updated ? CommonResponse.createForSuccess("申请已撤销") :
                CommonResponse.createForError("撤销失败");
    }

    // 教师修改借用申请（仅限待审批状态）
    @PutMapping("/update")
    public CommonResponse<?> updateBooking(@RequestBody ClassroomBooking updatedBooking) {
        ClassroomBooking original = bookingService.getById(updatedBooking.getId());
        if (original == null || !original.getTeacherId().equals(updatedBooking.getTeacherId())) {
            return CommonResponse.createForError("无效的借用申请或权限不足");
        }
        if (original.getStatus() != 0) {
            return CommonResponse.createForError("该申请已被审批，无法修改");
        }

        // 保留申请时间和状态
        updatedBooking.setApplyTime(original.getApplyTime());
        updatedBooking.setStatus(0); // 确保状态仍然是待审批
        boolean updated = bookingService.updateById(updatedBooking);
        return updated ? CommonResponse.createForSuccess("申请已修改") :
                CommonResponse.createForError("修改失败");
    }
    // 管理员审批借用：通过或拒绝
    @PutMapping("/review")
    public CommonResponse<?> reviewBooking(@RequestParam Long bookingId,
                                           @RequestParam int status, // 1=通过，2=拒绝
                                           @RequestParam(required = false) String remark,
                                           @RequestParam Long reviewerId) {
        ClassroomBooking booking = bookingService.getById(bookingId);
        if (booking == null) {
            return CommonResponse.createForError("借用记录不存在");
        }
        booking.setStatus(status);
        booking.setReviewerId(reviewerId);
        booking.setReviewTime(LocalDateTime.now());
        booking.setRemark(remark);
        boolean updated = bookingService.updateById(booking);
        return updated ? CommonResponse.createForSuccess("审批完成") :
                CommonResponse.createForError("审批失败");
    }

    @GetMapping("/by-teacher")
    public CommonResponse<List<ClassroomBookingDTO>> getByTeacherName(@RequestParam String teacherName) {
        List<ClassroomBookingDTO> list = bookingService.getBookingsByTeacherName(teacherName);
        return CommonResponse.createForSuccess(list);
    }
    // 管理员查看某个教室的所有借用记录（通过教室编号）
    @GetMapping("/by-classroom")
    public CommonResponse<List<ClassroomBookingDTO>> getByRoomNumber(@RequestParam String roomNumber) {
        List<ClassroomBookingDTO> list = bookingService.getBookingsByRoomNumber(roomNumber);
        return CommonResponse.createForSuccess(list);
    }

    // 获取所有已审批的借用记录，带教师姓名和教室号（管理员/公共查看）
    @GetMapping("/list")
    public CommonResponse<List<ClassroomBookingDTO>> getAllReviewedBookings() {
        List<ClassroomBookingDTO> list = bookingService.getAllReviewedWithNames();
        return CommonResponse.createForSuccess(list);
    }
//    /**
//     * 获取所有教室及其当天的借用状态
//     * @param date 查询日期 (YYYY-MM-DD)
//     * @return 教室列表及借用状态
//     */
//    @GetMapping("/classroom-status")
//    public CommonResponse<List<ClassroomDTO>> getAllClassroomsWithStatus(
//            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
//        List<ClassroomDTO> classroomStatusList = bookingService.getAllClassroomsWithBookingStatus(date);
//        return CommonResponse.createForSuccess(classroomStatusList);
//    }
    /**
     * 获取所有教室及其指定时间段的借用状态
     * @param queryStartTime 查询开始时间 (例如: 2025-07-07T09:00:00)
     * @param queryEndTime   查询结束时间 (例如: 2025-07-07T10:00:00)
     * @return 教室列表及借用状态
     */
    @GetMapping("/classroom-status")
    public CommonResponse<List<ClassroomDTO>> getAllClassroomsWithStatus(
            // 确保这里使用 LocalDateTime 和 ISO_DATE_TIME 格式
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime queryStartTime,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime queryEndTime) {

        // 获取所有教室
        List<Classroom> allClassrooms = classroomMapper.selectList(null);

        // 获取指定时间段内所有已批准的借用记录
        QueryWrapper<ClassroomBooking> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 1 表示已批准
                // 核心逻辑：判断现有预约时间段与查询时间段是否重叠
                // 重叠条件：(预约开始时间 < 查询结束时间) AND (预约结束时间 > 查询开始时间)
                .lt("start_time", queryEndTime) // 预约开始时间在查询结束时间之前
                .gt("end_time", queryStartTime); // 预约结束时间在查询开始时间之后

        List<ClassroomBooking> approvedBookings = bookingService.list(queryWrapper);

        Set<Long> bookedClassroomIds = approvedBookings.stream()
                .map(ClassroomBooking::getClassroomId)
                .collect(Collectors.toSet());

        // 封装为 ClassroomDTO
        List<ClassroomDTO> classroomDTOs = allClassrooms.stream().map(classroom -> {
            ClassroomDTO dto = new ClassroomDTO();
            dto.setId(classroom.getId());
            dto.setRoomNumber(classroom.getRoomNumber());
            dto.setLocation(classroom.getLocation());
            dto.setCapacity(classroom.getCapacity());
            // 判断当前教室是否在已批准的借用记录中
            dto.setStatus(bookedClassroomIds.contains(classroom.getId()));
            return dto;
        }).collect(Collectors.toList());

        return CommonResponse.createForSuccess(classroomDTOs);
    }

}